﻿using System;
using System.Collections.Generic;
using System.ServiceModel;
using __ts.Core.Log;

namespace __ts.Core.Plugin
{
    /// <summary>
    /// 
    /// </summary>
    /// <typeparam name="Contract"></typeparam>
    /// <typeparam name="Service"></typeparam>
    /// <typeparam name="Plugin"></typeparam>
    public abstract class PluginBase<Contract, Service, Plugin> : MarshalByRefObject, IPlugin
        where Service : Contract, new()
        where Plugin : new()
    {
        /// <summary>
        /// 
        /// </summary>
        protected PluginBase() { }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public static IPlugin GetInstance
        {
            get
            {
                if (_plugin == null)
                    _plugin = (IPlugin)new Plugin();
                return _plugin;
            }

        }
        private static IPlugin _plugin;
        /// <summary>
        /// 服务主机
        /// </summary>
        private ServiceHost _hosting;
        /// <summary>
        /// 远程对象生命周期
        /// </summary>
        /// <returns></returns>
        public override object InitializeLifetimeService() { return null; }
        /// <summary>
        /// 插件Key
        /// </summary>
        public abstract string Key { get; }
        /// <summary>
        /// 插件描述
        /// </summary>
        public abstract string Description { get; }
        /// <summary>
        /// 插件名称
        /// </summary>
        public string Name { get { return this.GetType().Namespace; } }
        /// <summary>
        /// 插件文件路径
        /// </summary>
        public string AssemblyPath { get { return this.GetType().Assembly.Location; } }
        /// <summary>
        /// 提供服务的端口
        /// </summary>
        public List<int> Ports { get { return PluginManager.GetInstance.Ports; } }
        /// <summary>
        /// 托管服务状态
        /// </summary>
        public CommunicationState State
        {
            get
            {
                if (this._hosting != null)
                    return this._hosting.State;
                return CommunicationState.Closed;
            }
        }
        /// <summary>
        /// 插件托管前事件
        /// </summary>
        public virtual void BeforeStartUp() { }
        /// <summary>
        /// 插件托管后事件
        /// </summary>
        public virtual void OnStartUp() { }
        /// <summary>
        /// 开始托管
        /// </summary>
        public bool Host()
        {
            BeforeStartUp();

            try
            {
                NetTcpBinding bind = new NetTcpBinding();
                bind.MaxReceivedMessageSize = 50971520;
                bind.ReceiveTimeout = new TimeSpan(0, 10, 0);
                bind.SendTimeout = new TimeSpan(0, 10, 0);
                bind.Security.Mode = SecurityMode.None;
                bind.PortSharingEnabled = true;
                bind.ReaderQuotas.MaxArrayLength = 2147483647;
                bind.Security.Transport.ClientCredentialType = TcpClientCredentialType.Windows;
                bind.Security.Message.ClientCredentialType = MessageCredentialType.Windows;

                _hosting = new ServiceHost(typeof(Service));
                for (int i = 0; i < this.Ports.Count; i++)
                {
                    _hosting.AddServiceEndpoint(typeof(Contract), bind, string.Format("net.tcp://localhost:{0}/{1}", this.Ports[i], this.Name));
                    //_hosting.Description.Endpoints[i].Behaviors.Add(new CCU.Core.Channel.CCUBehavior());
                }
                _hosting.Open();
            }
            catch (Exception ex)
            {
                Logger.Write(string.Format("{0} 服务托管失败。", this.Name));
                Logger.Write(ex);
                return false;
            }
            Logger.Write(string.Format("{0} 服务托管成功。", this.Name));

            OnStartUp();

            return true;
        }
        /// <summary>
        /// 停止托管
        /// </summary>
        public bool Unhost()
        {
            if (_hosting != null)
            {
                _hosting.Close();
                _hosting = null;
                Logger.Write(string.Format("{0} 服务停止托管成功。", this.Name));
                return true;
            }

            Logger.Write(string.Format("{0} 服务停止托管失败。", this.Name));
            return false;
        }
        /// <summary>
        /// 开始托管的时间
        /// </summary>
        public string HostDate
        {
            get;
            set;
        }
    }
}
